#pragma once
#include "base/function.h"
#include "net/connect.h"

#include "MyRpc/dataformat.h"
#include "MyRpc/rpc.h"
#include "MyRpc/rpccall.hpp"

#include <vector>
namespace myrpc
{
  class Message
  {
  public:
    // data_type种类
    ~Message() = default;
    bool Init_message(uint32_t type, message_func func);
    void Init_rpc();
    base::Rpc *Get_rpc();
    uint Consume_message(net_tools::net::Connect *connect, char *buf, uint size);
    static uint32_t Analyze_head(char *buf);
    static void Creat_head(uint32_t type, char *buf);
    static Message *Get_singleton()
    {
      static Message message;
      return &message;
    };

    template <typename... Datas>
    static bool Make_rpc(net_tools::net::Connect *connect, uint32_t type, char *buf, bool ret, Datas &&...datas)
    {
      Creat_head(4, buf);
      if (!connect->Write(buf, 4 + base::Rpccall<>::Make(type, buf + 4, ret, std::forward<Datas>(datas)...)))
      {
        return false;
      }
      return true;
    };

  private:
    Message(uint64_t message_size = base::Dataformat::data_type_size_);

    std::vector<message_func> func_vec_;
    uint32_t head_size_;
    base::Rpc rpc_;
  };

} // namespace myrpc